<?php
declare(strict_types=1);

namespace App\AdminApi\Module\System\Api;

use App\AdminApi\AdminApiBasicsController;
use App\AdminApi\Module\System\Service\CrontabLogService;
use App\AdminApi\Module\System\Service\CrontabService;
use Exception;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\{Controller, GetMapping, PostMapping};
use Psr\Http\Message\ResponseInterface;
use Zms\Guard\Auth;
use Zms\HyperfResponse\Response;

#[
    Auth(guard: self::GUARD, label: ['系统管理', '系统任务'], app: self::APP),
    Controller(prefix: "/admin-api/system-crontab", server: self::SERVER)
]
class CrontabController extends AdminApiBasicsController
{
    #[Inject]
    protected CrontabService $serve;

    #[Inject]
    protected CrontabLogService $logServe;

    #[
        GetMapping('list'),
        Auth(sign: 'system.crontab.list', describe: "查看系统任务信息", view: '/system/crontab/index')
    ]
    public function list(): ResponseInterface
    {
        return Response::Api()->success(data: $this->serve->getCrontabList());
    }


    #[
        PostMapping('run'),
        Auth(label: ['立即执行'], sign: 'system.crontab.run', describe: "立即执行任务")
    ]
    public function run(): ResponseInterface
    {
        $sign = $this->request->input('name');
        $list = $this->serve->getCrontabList();
        foreach ($list as $item) {
            if ($item['name'] === $sign) {
                $className = $item['callback'][0];
                $methodName = $item['callback'][1];
                $crontab = new $className;
                try {
                    $crontab->$methodName();
                    $this->serve->setCrontabLog($item['name'], true);
                    return Response::Api()->success('任务执行成功');
                } catch (Exception) {
                    $crontab->$methodName();
                    $this->serve->setCrontabLog($item['name'], false);
                    return Response::Api()->fail('任务执行失败');
                }
            }
        }
        return Response::Api()->fail('无效的任务');
    }


    #[
        GetMapping('log'),
        Auth(label: ['执行记录'], sign: 'system.crontab.log', describe: "任务执行记录")
    ]
    public function log(): ResponseInterface
    {
        $sign = $this->request->input('sign', '-1');
        $log = $this->logServe->search(['sign' => $sign])->orderByRaw('id DESC')->paginate(10);
        return Response::Api()->success(data: $log);
    }
}